#include <iostream>
#include <thread>
#include <mutex>
#include <random>
#include <chrono>
#include <vector>
#include <windows.h>

using namespace std;

class CSMA_CD_Network {
private:
    mutex channel_mutex;    // 模拟信道访问的互斥锁
    bool channel_busy = false;   // 信道状态
    bool collision_detected = false; // 冲突检测标志
    int num_stations;            // 站点数量

public:
    CSMA_CD_Network(int n) : num_stations(n) {}

    // 站点行为模拟
    void station_behavior(int station_id) {
        random_device rd;
        mt19937 gen(rd());
        uniform_real_distribution<> dis(0.0, 1.0);

        int collision_count = 0;
        const int max_attempts = 16; // 最大尝试次数

        while (collision_count < max_attempts) {
            // 1. 载波侦听 - 检查信道是否空闲
            {
                lock_guard<mutex> lock(channel_mutex);
                if (channel_busy) {
                    // 信道忙，等待随机时间后重试
                    this_thread::sleep_for(chrono::milliseconds(
                        static_cast<int>(dis(gen) * 100)));
                    continue;
                }
                // 占用信道
                channel_busy = true;
                collision_detected = false;
            }

            cout << "站点 " << station_id << " 开始传输数据..." << endl;

            // 2. 冲突检测 - 模拟传输过程中的冲突检测
            bool success = true;
            for (int i = 0; i < 3; ++i) { // 模拟传输过程中的多次检测
                this_thread::sleep_for(chrono::milliseconds(10));

                lock_guard<mutex> lock(channel_mutex);
                if (collision_detected) {
                    success = false;
                    break;
                }
            }

            // 3. 传输完成或冲突处理
            {
                lock_guard<mutex> lock(channel_mutex);
                if (success) {
                    cout << "站点 " << station_id << " 传输成功！" << endl;
                    channel_busy = false;
                    break; // 传输成功，退出循环
                } else {
                    // 检测到冲突
                    cout << "站点 " << station_id << " 检测到冲突！" << endl;
                    collision_count++;

                    // 4. 二进制指数退避算法
                    int backoff_time = (1 << (collision_count < 10 ? collision_count : 10)) - 1;
                    backoff_time = static_cast<int>(dis(gen) * backoff_time);

                    cout << "站点 " << station_id << " 等待 " << backoff_time
                              << " 个时隙后重试" << endl;

                    channel_busy = false;
                    this_thread::sleep_for(chrono::milliseconds(backoff_time * 10));
                }
            }
        }

        if (collision_count >= max_attempts) {
            cout << "站点 " << station_id << " 达到最大重试次数，放弃传输" << endl;
        }
    }

    // 模拟其他站点可能同时传输导致冲突
    void simulate_collision(int station_id) {
        random_device rd;
        mt19937 gen(rd());
        uniform_real_distribution<> dis(0.0, 1.0);

        if (dis(gen) > 0.7) { // 70%概率模拟冲突
            lock_guard<mutex> lock(channel_mutex);
            if (channel_busy && !collision_detected) {
                collision_detected = true;
                cout << "!!! 信道发生冲突 !!!" << endl;
            }
        }
    }
};

int main() {

    SetConsoleOutputCP(CP_UTF8);

    const int NUM_STATIONS = 3;
    CSMA_CD_Network network(NUM_STATIONS);

    vector<thread> stations;

    // 创建多个站点线程
    for (int i = 0; i < NUM_STATIONS; ++i) {
        stations.emplace_back([&network, i]() {
            network.station_behavior(i + 1);
        });
    }

    // 模拟冲突检测线程
    thread collision_thread([&network]() {
        for (int i = 0; i < 10; ++i) {
            this_thread::sleep_for(chrono::milliseconds(50));
            network.simulate_collision(i);
        }
    });

    // 等待所有线程完成
    for (auto& t : stations) {
        t.join();
    }
    collision_thread.join();

    return 0;
}